package com.sso.core.ssoauth.config;

import com.sso.core.ssoauth.service.impl.RandomAuthenticationKeyGenerator;
import com.sso.core.ssoauth.service.impl.RedisAuthorizationCodeServices;
import com.sso.core.ssoauth.service.impl.RedisClientDetailService;
import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;

/**
 * describe:
 *
 * @author 库琦
 * @date 2020/11/19/22:08
 */

@Configuration
@AllArgsConstructor
@EnableAuthorizationServer
public class AuthorizationServerConfig   extends AuthorizationServerConfigurerAdapter {
    private final AuthenticationManager authenticationManager;
    private final RedisConnectionFactory connectionFactory;
    private RedisAuthorizationCodeServices redisAuthorizationCodeServices;
    private final RedisClientDetailService redisClientDetailService;
    @Bean
    BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    /**
     *
     * @param clients  客户端信息全部刷入缓存。
     * @throws Exception
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.withClientDetails(redisClientDetailService);
        redisClientDetailService.loadAllClientToCache();
    }

    /**
     * 生成token信息
     * @return
     */
    @Bean
    public TokenStore tokenStore(){
        RedisTokenStore redisTokenStore = new RedisTokenStore(connectionFactory);
        redisTokenStore.setAuthenticationKeyGenerator(new RandomAuthenticationKeyGenerator());
        return redisTokenStore;
    }

    /**
     *配置系统需求
     * @param endpoints
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.allowedTokenEndpointRequestMethods(HttpMethod.GET,HttpMethod.POST)
         .authenticationManager(this.authenticationManager)
         .tokenStore(tokenStore())
                .authorizationCodeServices(redisAuthorizationCodeServices);
        //追加当前用户信息

    }

    /**
     * 表单不验证
     * @param security
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.allowFormAuthenticationForClients()
                .checkTokenAccess("isAuthenticated()");
        //允许已授权用户访问 获取 token 接口
        security.tokenKeyAccess("isAuthenticated()");

    }


}
